﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.BizTalk.Bam.EventObservation;
using System.Runtime.Serialization;
using Microsoft.BizTalk.Component.Interop;

namespace BizTalk.ESB.Extensions.Helpers
{
    [Serializable]
    public class BamWriter : ISerializable
    {
        private EventStream eventStream;

        public BamWriter(BamEventTypes writeType, string connectionString, int flushThreshold, int timeout)
        {
            if (writeType == BamEventTypes.Synchronous)
            {
                eventStream = InitDirectEventStream(connectionString, flushThreshold);
                eventStream.TimeoutValue = timeout;
            }
            else
            {
                eventStream = InitBufferedEventStream(connectionString, flushThreshold);
            }
        }

        public BamWriter(IPipelineContext PipelineContext)
        {
            eventStream = InitMessageEventStream(PipelineContext);
        }

        private BamWriter(SerializationInfo info, StreamingContext context)
        {
            // no state intended...
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            // no state intended...
        }

        #region Private Methods

        private EventStream InitDirectEventStream(string connectionString, int flushThreshold)
        {
            return new DirectEventStream(connectionString, flushThreshold);
        }

        private EventStream InitBufferedEventStream(string connectionString, int flushThreshold)
        {
            return new BufferedEventStream(connectionString, flushThreshold);
        }

        private EventStream InitMessageEventStream(IPipelineContext pipelineContext)
        {
            return pipelineContext.GetEventStream();
        }

        #endregion

        #region EventStream Methods

        public void AddReference(string activityName, string activityID, string referenceType, string referenceName, string referenceData)
        {
            eventStream.AddReference(activityName, activityID, referenceType, referenceName, referenceData);
        }

        public void AddReference(string activityName, string activityID, string referenceType, string referenceName, string referenceData,
        string longreferenceData)
        {
            eventStream.AddReference(activityName, activityID, referenceType, referenceName, referenceData, longreferenceData);
        }

        public void AddRelatedActivity(string activityName, string activityID, string relatedActivityName, string relatedTraceID)
        {
            eventStream.AddRelatedActivity(activityName, activityID, relatedActivityName, relatedTraceID);
        }

        public void BeginActivity(string activityName, string activityInstance)
        {
            eventStream.BeginActivity(activityName, activityInstance);
        }

        public void Clear()
        {
            eventStream.Clear();
        }

        public void EnableContinuation(string activityName, string activityInstance, string continuationToken)
        {
            eventStream.EnableContinuation(activityName, activityInstance, continuationToken);
        }

        public void EndActivity(string activityName, string activityInstance)
        {
            eventStream.EndActivity(activityName, activityInstance);
        }

        public void Flush()
        {
            eventStream.Flush();
        }

        public void StoreCustomEvent(IPersistQueryable singleEvent)
        {
            eventStream.StoreCustomEvent(singleEvent);
        }

        public void UpdateActivity(string activityName, string activityInstance, params object[] data)
        {
            eventStream.UpdateActivity(activityName, activityInstance, data);
        }

        #endregion
    }
}
